home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
oper_sys
/
prospero
/
propsero.lha
/
prospero-beta.4.2e
/
user
/
archie.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-02-10
|
10KB
|
352 lines
/*
* Copyright (c) 1991 by the University of Washington
*
* For copying and distribution information, please see the file
* <uw-copyright.h>.
*
* Written by Clifford Neuman (bcn@isi.edu) with changes by
* Brendan Kehoe (brendan@cs.widener.edu) and
* George Ferguson (ferguson@cs.rochester.edu).
*/
#include <uw-copyright.h>
#include <stdio.h>
#include <sys/time.h>
#include <pfs.h>
#include <perrno.h>
#include <rdgram.h>
#include <archie.h>
char *month_sname();
char *index();
long time();
void display_link();
int pfs_debug = 0;
int perrno;
int pwarn;
/*
* Archie client using the Prospero protocol
*
* archie [-[cers][l][t][N #][m #][h host]] search-string
*
* Send a query to Prospero server on host running
* Archie, collect, process, and display results.
*
* OPTIONS:
* -c : case sensitive substring search
* -e : exact string match (default)
* -r : regular expression search
* -s : case insensitive substring search
* -l : list one match per line
* -t : sort inverted by date
* -N# or -N # : specifies query niceness level (# optional 0-35765)
* -m# or -m # : specifies maximum number of hits to return
* -h host : specifies server host
*
* -D# or -D # : Debug level (# optional)
*
* If -e is specified in addition to either -r, -s, or -c,
* then server will try an exact match before falling back
* to a more expensive method.
*/
main(argc,argv)
int argc;
char *argv[];
{
char *cur_arg; /* For argument parsing */
char *progname = argv[0];
VLINK results; /* List of matched links */
VLINK l; /* Temporary link pointer */
char qtype = '='; /* Default to exact string match */
char etype = '='; /* Type if only -e is specified */
int eflag = 0; /* Exact flag specified */
int max_hits = MAX_HITS; /* Number of links to be returned */
int offset = 0; /* Skiping over this many */
int listflag = 0; /* List one match per line */
int (*cmp_proc)(); /* Sort method */
int versionflag = 0; /* Display release identifier */
char *host = ARCHIE_HOST; /* Host to send query */
int tmp;
cmp_proc = AQ_DEFCMP; /* Default sorting method */
argc--;argv++;
while (argc > 0 && **argv == '-') {
cur_arg = argv[0]+1;
/* If a - by itself, or --, then no more arguments */
if(!*cur_arg || ((*cur_arg == '-') && (!*(cur_arg+1)))) {
argc--, argv++;
goto scandone;
}
while (*cur_arg) {
switch (*cur_arg++) {
case 'D': /* debug level */
pfs_debug = 1; /* Default debug level */
if(*cur_arg && index("0123456789",*cur_arg)) {
sscanf(cur_arg,"%d",&pfs_debug);
cur_arg += strspn(cur_arg,"0123456789");
}
else if(argc > 2) {
tmp = sscanf(argv[1],"%d",&pfs_debug);
if (tmp == 1) {argc--;argv++;}
}
break;
case 'N': /* priority (nice) */
rdgram_priority = RDGRAM_MAX_PRI; /* Use this if no # */
if(*cur_arg && index("-0123456789",*cur_arg)) {
sscanf(cur_arg,"%d",&rdgram_priority);
cur_arg += strspn(cur_arg,"-0123456789");
}
else if(argc > 2) {
tmp = sscanf(argv[1],"%d",&rdgram_priority);
if (tmp == 1) {argc--;argv++;}
}
if(rdgram_priority > RDGRAM_MAX_SPRI)
rdgram_priority = RDGRAM_MAX_PRI;
if(rdgram_priority < RDGRAM_MIN_PRI)
rdgram_priority = RDGRAM_MIN_PRI;
break;
case 'c': /* substring (case sensitive) */
qtype = 'C';
etype = 'c';
break;
case 'e': /* exact match */
/* If -e specified by itself, then we use the */
/* default value of etype which is must be '=' */
eflag++;
break;
case 'h': /* host */
host = argv[1];
argc--;argv++;
break;
case 'l': /* list one match per line */
listflag++;
break;
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
cur_arg--;
case 'm': /* max hits */
max_hits = -1;
if(*cur_arg && index("0123456789",*cur_arg)) {
sscanf(cur_arg,"%d",&max_hits);
cur_arg += strspn(cur_arg,"0123456789");
}
else if(argc > 1) {
tmp = sscanf(argv[1],"%d",&max_hits);
if(tmp == 1) {argc--;argv++;}
}
if(max_hits < 1) {
fprintf(stderr, "%s: -m option requires a value for max hits (>= 1)\n",
progname);
exit(1);
}
break;
case 'o': /* offset */
if(*cur_arg && index("0123456789",*cur_arg)) {
sscanf(cur_arg,"%d",&offset);
cur_arg += strspn(cur_arg,"0123456789");
}
else if(argc > 1) {
tmp = sscanf(argv[1],"%d",&offset);
if(tmp == 1) {argc--;argv++;}
}
if(offset < 0) {
fprintf(stderr, "%s: -o option requires a value for offset (>= 0)\n",
progname);
exit(1);
}
break;
case 'r': /* regular expression search */
qtype = 'R';
etype = 'r';
break;
case 's': /* substring (case insensitive) */
qtype = 'S';
etype = 's';
break;
case 't': /* sort inverted by date */
cmp_proc = AQ_INVDATECMP;
break;
case 'v': /* display version */
fprintf(stderr,"Prospero client - Version %s\n",
PFS_RELEASE);
versionflag++;
break;
default:
fprintf(stderr,"Usage: %s [-[cers][l][t][N #][m #][h host]] search-string\n", progname);
exit(1);
}
}
argc--, argv++;
}
scandone:
/* If -e specified, then choose the exact version of -crs option */
if(eflag) qtype = etype;
/* If only -v specified, return, but not an error */
if((argc != 1) && versionflag) exit(0);
if(argc != 1) {
fprintf(stderr,"Usage: %s [-[cers][l][t][N #][m #][h host]] search-string\n", progname);
fprintf(stderr," -c : case sensitive substring search\n");
fprintf(stderr," -e : exact string match (default)\n");
fprintf(stderr," -r : regular expression search\n");
fprintf(stderr," -s : case insensitive substring search\n");
fprintf(stderr," -l : list one match per line\n");
fprintf(stderr," -t : sort inverted by date\n");
fprintf(stderr," -N # : specifies query niceness level (optional 0-35765)\n");
fprintf(stderr," -m # : specifies maximum number of hits to return\n");
fprintf(stderr," -h host : specifies server host\n");
exit(1);
}
perrno = 0; *p_err_string = '\0';
pwarn = 0; *p_warn_string = '\0';
results = archie_query(host,argv[0],max_hits,offset,qtype,cmp_proc,0);
if(!results && perrno) {
fprintf(stderr,"%s",progname);
perrmesg(" failed: ",0,NULL);
exit(1);
}
if(pwarn) pwarnmesg("WARNING: ",0,NULL);
/* Display the results */
for(l = results; l; l = l->next) display_link(l,listflag);
if(!listflag) printf("\n");
vllfree(l);
exit(0);
}
/*
* display_link: Prints the value of a virtual link. If listflag is 0,
* then the link is displayed in a format suitable for
* reading by humans. If listflag is non-zero all
* information is printed on a single line in a form
* suitable for parsing by programs.
*
* NOTE: If listflag is zero, this procedure uses static variables
* to detect when fields have changed since the last call.
* The display of field unchanged since the last call is
* suppressed.
*/
void
display_link(l,listflag)
VLINK l; /* Link to be displayed */
int listflag; /* non-zero = List one match per line */
{
static char lastpath[MAX_VPATH] = "\001";
static char lasthost[MAX_VPATH] = "\001";
static struct tm *presenttime = NULL;
long now;
char linkpath[MAX_VPATH];
char archie_date[20];
int dirflag = 0;
int size = 0;
char *modes = "";
char *gt_date = "";
int gt_year = 0;
int gt_mon = 0;
int gt_day = 0;
int gt_hour = 0;
int gt_min = 0;
PATTRIB ap;
/* First time called, set localtime */
if(!presenttime) {
(void) time(&now);
presenttime = localtime(&now);
}
/* Initialize local buffers */
*archie_date = '\0';
/* Remember if we're looking at a directory */
if (sindex(l->type,"DIRECTORY")) dirflag = 1;
else dirflag = 0;
/* Extract the linkpath from the filename */
strcpy(linkpath,l->filename);
*(linkpath + (strlen(linkpath) - strlen(l->name) - 1)) = '\0';
/* Is this a new host? */
if (strcmp(l->host,lasthost) != 0) {
if (!listflag)
printf("\nHost %s\n\n",l->host);
strcpy(lasthost,l->host);
*lastpath = '\001';
}
/* Is this a new linkpath (location)? */
if(strcmp(linkpath,lastpath) != 0) {
if (!listflag)
printf(" Location: %s\n",(*linkpath ? linkpath : "/"));
strcpy(lastpath,linkpath);
}
/* Parse the attibutes of this link */
for (ap = l->lattrib; ap; ap = ap->next) {
if (strcmp(ap->aname,"SIZE") == 0) {
sscanf(ap->value.ascii,"%d",&size);
} else if(strcmp(ap->aname,"UNIX-MODES") == 0) {
modes = ap->value.ascii;
} else if(strcmp(ap->aname,"LAST-MODIFIED") == 0) {
gt_date = ap->value.ascii;
sscanf(gt_date,"%4d%2d%2d%2d%2d",>_year,
>_mon, >_day, >_hour, >_min);
if ((12 * (presenttime->tm_year + 1900 - gt_year) +
presenttime->tm_mon - gt_mon) > 6)
sprintf(archie_date,"%s %2d %4d",month_sname(gt_mon),
gt_day, gt_year);
else
sprintf(archie_date,"%s %2d %02d:%02d",month_sname(gt_mon),
gt_day, gt_hour, gt_min);
}
}
/* Print this link's information */
if (listflag)
printf("%s %6d %s %s%s\n",gt_date,size,l->host,l->filename,
(dirflag ? "/" : ""));
else
printf(" %9s %s %10d %s %s\n",(dirflag ? "DIRECTORY" : "FILE"),
modes,size,archie_date,l->name);
/* Free the attibutes */
atlfree(l->lattrib);
l->lattrib = NULL;
}